package com.imooc.maokeyang.alllearning.controller;


import com.imooc.maokeyang.alllearning.domain.common.PageQuery;
import com.imooc.maokeyang.alllearning.domain.common.PageResult;
import com.imooc.maokeyang.alllearning.domain.common.ResponseResult;
import com.imooc.maokeyang.alllearning.domain.dto.UserDTO;
import com.imooc.maokeyang.alllearning.domain.dto.UserQueryDTO;
import com.imooc.maokeyang.alllearning.domain.vo.UserVO;
import com.imooc.maokeyang.alllearning.exception.ErrorCodeEnum;
import com.imooc.maokeyang.alllearning.service.ExcelExportService;
import com.imooc.maokeyang.alllearning.service.UserService;
import com.imooc.maokeyang.alllearning.util.InsertValidationGroup;
import com.imooc.maokeyang.alllearning.util.UpdateValidationGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 只有类开启了@Validated, 那么类方法中 @NotNull 简单注解对基础数据 才会生效
 */
@RestController
@RequestMapping("/api/users")
@Validated
@Slf4j
@Api(tags = "用户API接口")
public class UserController {


    @Autowired
    private UserService userService;

    @Autowired
    private ExcelExportService excelExportService;

    /**
     * 新增用户
     * POST /api/users UserDTO
     */
    @ApiOperation(value = "新增用户", notes = "新增用户")
    @PostMapping
    public ResponseResult save(@Validated(InsertValidationGroup.class)
                               @RequestBody UserDTO userDTO) {


        int save = userService.save(userDTO);

        if (save == 1) {
            return ResponseResult.success("新增成功");
        }

        return ResponseResult.failure(ErrorCodeEnum.INSERT_FAILURER);
    }


    /**
     * 更新用户信息
     * PUT /api/users/{id} UserDTO
     */
    @ApiOperation(value = "更新用户", notes = "更新用户")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "id", value = "用户ID",
                    paramType = "path",
                    dataTypeClass = Long.class,
                    required = true,
                    example = "1"),
            @ApiImplicitParam(
                    name = "userDTO", value = "更新的数据",
                    paramType = "body",
                    dataTypeClass = UserDTO.class,
                    required = true)
    }
    )
    @PutMapping("/{id}")
    public ResponseResult update(@NotNull @PathVariable("id") Long id,
                                 @Validated(UpdateValidationGroup.class)
                                 @RequestBody UserDTO userDTO) {

        int update = userService.update(id, userDTO);

        if (update == 1) {
            return ResponseResult.success("更新成功");
        }

        return ResponseResult.failure(ErrorCodeEnum.UPDATE_FAILURER);
    }

    /**
     * 删除用户信息
     *
     * Delete /api/users/{id}
     */
    @ApiOperation(value = "删除用户", notes = "删除用户")
    @ApiImplicitParam(
            name = "pageNo", value = "当前页码",
            paramType = "path",
            dataTypeClass = Long.class,
            required = true,
            example = "1")
    @DeleteMapping("/{id}")
    public ResponseResult delete(@NotNull(message = "ID不能为空")
                                 @PathVariable Long id) {

        // http://wangha.com/user/1?name=xiaoming   @RequestParam()
        int delete = userService.delete(id);

        if (delete == 1) {
            return ResponseResult.success("删除成功");
        }

        return ResponseResult.failure(ErrorCodeEnum.DELETE_FAILURER);
    }


    /**
     *
     * 查询用户信息
     *
     * @return
     */
    @ApiOperation(value = "查询用户列表", notes = "返回用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "pageNo", value = "当前页码",
                    paramType = "query",
                    dataTypeClass = Integer.class,
                    required = true,
                    example = "1"),
            @ApiImplicitParam(
                    name = "pageSize", value = "分页size",
                    paramType = "query",
                    dataTypeClass = Integer.class,
                    required = true,
                    example = "2"),
//            @ApiImplicitParam(
//                    name = "query", value = "查询条件",
//                    paramType = "body",
//                    dataTypeClass = UserQueryDTO.class,
//                    required = true)
        }
    )
    @GetMapping
    public ResponseResult<PageResult> query(@NotNull Integer pageNo,
                                            @NotNull Integer pageSize,
                                            @Validated @RequestBody UserQueryDTO query) {

        PageQuery<UserQueryDTO> pageQuery = new PageQuery<>();

        pageQuery.setPageNo(pageNo);
        pageQuery.setPageSize(pageSize);
        pageQuery.setQuery(query);

        PageResult<List<UserDTO>> pageResult = userService.query(pageQuery);

        List<UserVO> userVOList = Optional.ofNullable(pageResult.getData())
                .map(List::stream)
                .orElseGet(Stream::empty)
                .map(userDTO -> {

                    UserVO userVO = new UserVO();
                    BeanUtils.copyProperties(userDTO, userVO);
                    // 特殊字段做处理
                    userVO.setPassword("****");

                    return userVO;

                }).collect(Collectors.toList());

        // 封装返回结果
        PageResult<List<UserVO>> result = new PageResult<>();
        BeanUtils.copyProperties(pageResult, result);
        result.setData(userVOList);


        return ResponseResult.success(result);
    }


    /**
     * 数据导出
     *
     * @param query
     * @param filename
     * @return
     */
    @GetMapping("/export")
    public ResponseResult<Boolean> export(@Validated UserQueryDTO query,
                                          @NotEmpty String filename) {
        // 数据导出
        excelExportService.export(query, filename);

        return ResponseResult.success(Boolean.TRUE);
    }
}
